Most loops are governed by one or more
for clauses. A for clause
simultaneously describes variables to be bound, how those
variables are to be stepped during the loop, and usually an end
condition based on those variables.
The word as is a synonym for the word
for. This word is followed by a variable name, then
a word like from or across that
describes the kind of iteration desired. In Common Lisp, the
phrase being the sometimes precedes the type of
iteration; in this package both being and
the are optional. The word each is a
synonym for the, and the word that follows it may be
singular or plural: ‘for x being
the elements of y’ or
‘for x being each element of
y’. Which form you use is purely a matter of
style.
The variable is bound around the loop as if by
let:
(setq i 'happy)
(loop for i from 1 to 10 do (do-something-with i))
i
⇒ happy
for var from
expr1 to expr2
by expr3for clause creates a counting loop.
Each of the three sub-terms is optional, though there must be
at least one term so that the clause is marked as a counting
clause.
The three expressions are the starting value, the ending
value, and the step value, respectively, of the variable. The
loop counts upwards by default (expr3 must be
positive), from expr1 to expr2
inclusively. If you omit the from term, the loop
counts from zero; if you omit the to term, the
loop counts forever without stopping (unless stopped by some
other loop clause, of course); if you omit the
by term, the loop counts in steps of one.
You can replace the word from with
upfrom or downfrom to indicate the
direction of the loop. Likewise, you can replace
to with upto or
downto. For example, ‘for x from 5 downto 1’ executes
five times with x taking on the integers from 5
down to 1 in turn. Also, you can replace to with
below or above, which are like
upto and downto respectively except
that they are exclusive rather than inclusive limits:
(loop for x to 10 collect x)
⇒ (0 1 2 3 4 5 6 7 8 9 10)
(loop for x below 10 collect x)
⇒ (0 1 2 3 4 5 6 7 8 9)
The by value is always positive, even for
downward-counting loops. Some sort of from value
is required for downward loops; ‘for x downto 5’ is not a valid
loop clause all by itself.
for var in
list by functionby
term, then function is used to traverse the list
instead of cdr; it must be a function taking one
argument. For example:
(loop for x in '(1 2 3 4 5 6) collect (* x x))
⇒ (1 4 9 16 25 36)
(loop for x in '(1 2 3 4 5 6) by 'cddr collect (* x x))
⇒ (1 9 25)
for var on
list by function
(loop for x on '(1 2 3 4) collect x)
⇒ ((1 2 3 4) (2 3 4) (3 4) (4))
With by, there is no real reason that the
on expression must be a list. For example:
(loop for x on first-animal by 'next-animal collect x)
where (next-animal x) takes
an “animal” x and returns the next in
the (assumed) sequence of animals, or nil if
x was the last animal in the sequence.
for var in-ref
list by functionin clause, but
var becomes a setf-able
“reference” onto the elements of the list rather
than just a temporary variable. For example,
(loop for x in-ref my-list do (incf x))
increments every element of
my-list in place. This clause is an extension to
standard Common Lisp.
for var across
array
(loop for x across "aeiou"
do (use-vowel (char-to-string x)))
for var across-ref
arraysetf-able reference onto the elements; see
in-ref above.for var being the elements
of sequencein or
across. The clause may be followed by the
additional term ‘using
(index var2)’ to cause var2 to be
bound to the successive indices (starting at 0) of the
elements.
This clause type is taken from older versions of the
loop macro, and is not present in modern Common
Lisp. The ‘using (sequence
...)’ term of the older macros is not
supported.
for var being the elements
of-ref sequencesetf-able reference onto the elements; see
in-ref above.for var being the symbols
[of obarray]As an example,
(loop for sym being the symbols
when (fboundp sym)
when (string-match "^map" (symbol-name sym))
collect sym)
returns a list of all the functions whose names begin with ‘map’.
The Common Lisp words external-symbols and
present-symbols are also recognized but are
equivalent to symbols in Emacs Lisp.
Due to a minor implementation restriction, it will not
work to have more than one for clause iterating
over symbols, hash tables, keymaps, overlays, or intervals in
a given loop. Fortunately, it would rarely if
ever be useful to do so. It is valid to mix one of
these types of clauses with other clauses like for ...
to or while.
for var being the hash-keys
of hash-tablehash-values
is the opposite word of the word following the) to
cause var and var2 to be bound to the two
parts of each hash table entry.for var being the key-codes
of keymapusing clause to access both the codes and the
bindings together.for var being the key-seqs
of keymapfor var being the overlays
[of buffer] ...extents is synonymous with
overlays). If the of term is omitted,
the current buffer is used. This clause also accepts optional
‘from
pos’ and ‘to pos’ terms, limiting
the clause to overlays which overlap the specified
region.for var being the intervals
[of buffer] ...of, from,
to, and property terms, where the
latter term restricts the search to just the specified
property. The of term may specify either a buffer
or a string.for var being the
framesscreens is a synonym for frames. The
frames are visited in next-frame order starting
from selected-frame.for var being the windows
[of frame]next-window order starting from
selected-window (or
frame-selected-window if you specify
frame). This clause treats the minibuffer window in
the same way as next-window does. For greater
flexibility, consider using walk-windows
instead.for var being the
buffersfor var =
expr1 then expr2
(loop for x on my-list by 'cddr do ...)
(loop for x = my-list then (cddr x) while x do ...)
Note that this type of for clause does not
imply any sort of terminating condition; the above example
combines it with a while clause to tell when to
end the loop.
If you omit the then term, expr1
is used both for the initial setting and for successive
settings:
(loop for x = (random) when (> x 0) return x)
This loop keeps taking random numbers
from the (random) function until it gets a
positive one, which it then returns.
If you include several for clauses in a row, they
are treated sequentially (as if by let* and
setq). You can instead use the word and
to link the clauses, in which case they are processed in parallel
(as if by let and psetq).
(loop for x below 5 for y = nil then x collect (list x y))
⇒ ((0 nil) (1 1) (2 2) (3 3) (4 4))
(loop for x below 5 and y = nil then x collect (list x y))
⇒ ((0 nil) (1 0) (2 1) (3 2) (4 3))
In the first loop, y is set
based on the value of x that was just set by the
previous clause; in the second loop, x and
y are set simultaneously so y is set
based on the value of x left over from the previous
time through the loop.
Another feature of the loop macro is
destructuring, similar in concept to the destructuring
provided by defmacro. The var part of any
for clause can be given as a list of variables
instead of a single variable. The values produced during loop
execution must be lists; the values in the lists are stored in
the corresponding variables.
(loop for (x y) in '((2 3) (4 5) (6 7)) collect (+ x y))
⇒ (5 9 13)
In loop destructuring, if there are more values than variables
the trailing values are ignored, and if there are more variables
than values the trailing variables get the value
nil. If nil is used as a variable name,
the corresponding values are ignored. Destructuring may be
nested, and dotted lists of variables like (x . y)
are allowed.